#include "../include/cWindowBuffer.h"


cWindowBuffer::cWindowBuffer(int wsize,int bsize)
  :window_size(wsize),window_len(0),buffer_size(bsize),buffer_len(0),first(-1),last(-1),last_buff(-1),total_size(bsize+wsize)
{
  this->data = new uint8_t[this->total_size];
}

cWindowBuffer::~cWindowBuffer()
{
    delete [] this->data;
}

void cWindowBuffer::clear()
{
  //set initiat values to pointers and zero lengths
  this->first=-1;
  this->last=-1;
  this->last_buff=-1;
  this->buffer_len=0;
  this->window_len=0;
}

int cWindowBuffer::get_window_length()
{
  return this->window_len;
}

int cWindowBuffer::get_buffer_length()
{
  return this->buffer_len;
}
int cWindowBuffer::get_window_size()
{
  return this->window_size;
}

int cWindowBuffer::get_buffer_size()
{
  return this->buffer_size;
}

uint8_t & cWindowBuffer::operator[](const unsigned int index)
{
  if(this->first == -1)
    return this->data[0];
  return this->data[(this->first+index)%this->total_size];
}

uint8_t & cWindowBuffer::operator()(const unsigned int index)
{
  if(this->last_buff == -1)
    return this->data[0];
  return this->data[(this->last+1+index)%this->total_size];
}

void cWindowBuffer::flush_buffer()
{
  if(this->buffer_len==0 || this->last_buff==-1)
  {
    this->buffer_len=0;
    this->last_buff=-1;
    return;
  }
  if(this->first==-1 || this->last==-1)
   this->first=0;
  this->last = this->last_buff;
  this->window_len+=this->buffer_len;
  if(this->window_len > this->window_size)
  { 
    this->first = (this->first + this->window_len-this->window_size)%this->total_size;
    this->window_len = this->window_size;
  }
  this->clear_buffer();
}

void cWindowBuffer::buffer(uint8_t val)
{
  if(this->buffer_len >= this->buffer_size)
    this->flush_buffer();
  if(this->buffer_len <= 0)
    this->last_buff = (this->last+1)%this->total_size;
  else
    this->last_buff = (this->last_buff+1)%this->total_size;
  this->data[this->last_buff] = val;
  this->buffer_len++;
}

void cWindowBuffer::insert(uint8_t val)
{
  if(this->buffer_len)
    this->flush_buffer();
  if(this->first == -1 || this->last == -1)
  {
    this->first=0;
    this->last=0;
  }
  else
    this->last = (this->last+1)%this->total_size;
  this->data[this->last] = val;
  if(this->window_len < this->window_size)
    this->window_len++;
  else
    this->first = (this->first+1)%this->total_size;
}
void cWindowBuffer::clear_buffer()
{
  this->buffer_len=0;
  this->last_buff=-1;
}
